package com.kinroy.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kinroy.reggie.common.R;
import com.kinroy.reggie.entity.*;
import com.kinroy.reggie.service.CategoryService;
import com.kinroy.reggie.service.DishFlavorService;
import com.kinroy.reggie.service.DishService;
import com.kinroy.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {
    @Autowired
    private DishService ds;

    @Autowired
    private CategoryService cs;


    /*分页显示菜品功能*/
    @GetMapping("/page")
    public R<IPage> getbypage(HttpServletRequest request, String name) {
        //取出分页条件
        Long page = Long.valueOf(request.getParameter("page"));
        Long pageSize = Long.valueOf(request.getParameter("pageSize"));
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper();
        /*模糊查询即可*/
        lqw.like(name != null, Dish::getName, name);
        /*设置排序方式，也就是设置成根据更新时间降序来排，更符合我们的使用逻辑，更新了的在前面*/
        lqw.orderByDesc(Dish::getUpdateTime);

        //在我们的菜品展示中，还有一个属性是当前菜品的菜品分类，而这个属性在前端要接收的值
        //是我们当前dish菜品的 categoryId 对应的 那个分类的 categoryName 属性，
        /*也就是说，我们还需要去根据dish的categoryId 去查category表中对应的categoryId 的
         * categoryName 是多少，然后用dishDto封装起来（dishDto中加了categoryName的属性），再传给前端进行显示。
         *  */

        IPage<Dish> dishIPage = new Page<>(page, pageSize);
        /*查询后的结果*/
        IPage<Dish> page1 = ds.page(dishIPage);

        IPage<DishDto> dishDtoIPage = new Page<>();

        /*通过对象拷贝，把分好页的dish的数据拷贝的 dishDto中，然后我们在为里面的数据逐一加上对应的categoryName
         * 因为再分页对象Page中，我们分好页的数据是存在 其 records 属性中的，我们要把这个list里面的数据每一个对应
         * 加上categoryName，所以拷贝的时候就不拷贝 这个  records 属性，方便我们后面对它进行处理
         * */

        //通过一个工具类来实现数据拷贝，BeanUtil 的copyproperties（被拷贝的对象，拷贝到的对象,表明不拷贝的属性）
        BeanUtils.copyProperties(page1, dishDtoIPage, "records");

        //对分页数据进行逐一加上对应的categoryName
        List<Dish> dishes = page1.getRecords();

        List<DishDto> list = dishes.stream().map((item) -> {
            Long categoryId = item.getCategoryId();
            Category byId = cs.getById(categoryId);
            String categoryName = byId.getName();
            DishDto dishDto = new DishDto();
            dishDto.setCategoryName(categoryName);
            /*把除了CategoryName的其他属性对应拷贝到dishDto中去*/
            BeanUtils.copyProperties(item, dishDto);
            return dishDto;
        }).collect(Collectors.toList());
        dishDtoIPage.setRecords(list);
        return R.success(dishDtoIPage);

    }

    /*添加菜品功能*/
    @PostMapping
    public R<String> add(@RequestBody DishDto dish) {
        /*boolean save = ds.save(dish);
        List<DishFlavor> flavors = dish.getFlavors();
        for (int i = 0; i < flavors.size(); i++) {
            DishFlavor dishFlavor = flavors.get(i);
            dishFlavor.setDishId(dish.getId());
            boolean save1 = dfs.save(dishFlavor);
            if (save1 != true) {
                return R.error("未知错误！");
            }
        }
        if (save) {
            return R.success("添加菜品成功！");
        }*/

        /*虽然上面的写法也能实现我们的业务需求，但是因为涉及到多个数据库表的操作，那么按照之前的开发规范，
         * 多个表的操作，实现起来要么同成功，要么同失败，即是一个事务，所以我们应该在dish对应的dishServiceImpl中
         * 去写上对应的业务，并加上 @Transactional 注解表示为事务，同时在spring的配置类中也要加上 @EnableTransactionManagement
         * 表示声明可以允许事务实现
         * */

        ds.saveWithDishFlavor(dish);
        return R.success("新增菜品成功！");
    }

    /*编辑功能的数据回显*/
    @GetMapping("/{id}")
    public R<DishDto> show(@PathVariable Long id) {
        DishDto show = ds.show(id);
        return R.success(show);
    }

    /*修改菜品信息功能*/
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto) {
        ds.updateWithDishFlavor(dishDto);
        return R.success("修改成功！");
    }

    /*删除菜品功能（包含批量删除）*/
    @DeleteMapping
    public R<String> delete(Long[] ids){
        log.info("前端传来的要删除的菜品id为{}",ids);
        List<Long> Ids=new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            Ids.add(ids[i]);
        }
        boolean b = ds.removeByIds(Ids);
        if (b){
            return R.success("删除成功！");
        }
        return R.error("删除失败！");
    }

    /*停售菜品功能(包含批量停售)*/
    @PostMapping("status/0")
    public R<String> stopSell(Long[] ids){
        log.info("前端传过来要停售的id为{}",ids);
        boolean check=true;
        for (int i = 0; i < ids.length; i++) {
            UpdateWrapper<Dish> uw=new UpdateWrapper<>();
            uw.lambda().set(Dish::getStatus,0);
            uw.lambda().eq(Dish::getId,ids[i]);
            boolean update = ds.update(uw);
            check=check&&update;
        }
        if (check){
            return R.success("停售操作成功！");
        }
        return R.error("停售操作失败！");
    }

    /*起售菜品功能(包含批量起售)*/
    @PostMapping("/status/1")
    public R<String> sellOpen(Long[] ids){
        log.info("前端传过来要起售的id为{}",ids);
        boolean check=true;
        for (int i = 0; i < ids.length; i++) {
            UpdateWrapper<Dish> uw=new UpdateWrapper<>();
            uw.lambda().set(Dish::getStatus,1);
            uw.lambda().eq(Dish::getId,ids[i]);
            boolean update = ds.update(uw);
            check=check&&update;
        }
        if (check){
            return R.success("起售操作成功！");
        }
        return R.error("启售操作失败！");
    }

    /*套餐管理中添加套餐的添加菜品功能回显功能*/
    @GetMapping("/list")
    public R<List<DishDto>> dishShowBack(Long categoryId,Long status,String name){
        log.info("前端传来的菜系的categoryId为{}",categoryId);
        log.info("移动端传来的status为{}",status);

        //在套餐中添加菜品时可以通过菜名搜索出来菜品来添加
        if (name!=null){
            LambdaQueryWrapper<Dish> lqw=new LambdaQueryWrapper<>();
            lqw.eq(Dish::getName,name);
            Dish one = ds.getOne(lqw);
            DishDto dishDto=new DishDto();
            BeanUtils.copyProperties(one,dishDto);
            List<DishDto> dishDtoList=new ArrayList<>();
            dishDtoList.add(dishDto);
            return R.success(dishDtoList);
        }
        /*LambdaQueryWrapper<Dish> lqw=new LambdaQueryWrapper<>();

        lqw.eq(Dish::getCategoryId,categoryId);

        List<Dish> list = ds.list(lqw);

        return R.success(list);*/

        List<DishDto> dishDtos = ds.listwithDishFlavor(categoryId, status);
        return R.success(dishDtos);
    }
}
